/**
 * @class   wosh::IReflection
 * @brief   
 *
 *
 *
 *
punti:
 - INHERITANCE/INTERFACES
! - Object::Type, Bundle::Interfaces

 - METHODS sono A PARTE		MA vanno rivisti..
  - architettura semplice
  - accesso altissimo livello (function pointer)
  - supportano self-modification

 - PROPERTIES sono A PARTE		MA vanno rivisti..
  - architettura semplice
  - accesso altissimo livello (Data holder)

 - CONTAINER
! - da pensare: LIST, TABLE, TREE
! - container generici, children dei bundles

 - DISTRIBUTION
!  - same code for local object and remote object => usare adapters
			DISTRIBUTION deals with certain distribution-specific issues, such as network failure and distributed memory management, while core reflection does not

---------------------------------------------------------------------------------------------------------
anche permission e sua ereditariet VA RIPENSATA!

---------------------------------------------------------------------------------------------------------

Run Time Type Identification (RTTI) provides some information about objects at run time such as the name of its type. The C++ language has RTTI support, which fulfills the minimal requirements

Terminology: Reflective language architectures may be characterized in terms of their support for:
	Introspection
	. The ability of a program to examine its own
	structure.
	2. Self-modification
	. The ability of a program to change its own
	structure.
	3. Execution of dynamically generated code
	. The ability to
	execute program fragments that are not statically known. This
	is a special case of 2.
	4. Intercession
	. The ability to modify the semantics of the
	underlying programming language from within the language
	itself (the term intercession is sometimes used in a broader
	sense in parts of the literature, but we adopt the narrower definition
	of intercession given here, based on [18]).



Consider the following scenario.
	A programmer writes a class
	browser, using reflection. At a later time, it becomes necessary to
	browse classes on remote machines. We would like to reuse as
	much of our browser code as possible, with as little adaptation as
	possible.
	This goal may seem controversial; readers should note that we are
	not arguing for (or against) transparent distribution. That controversy
	is far outside the scope of this paper. Rather, we argue that
	mirrors are a good approach to the design of a reflective API that
	is
	distribution-aware. We also claim that a mirror-based, distribution
	aware reflective API can be designed so that it serves for the nondistributed
	case as well.


Meta-Object Protocol (MOP)" and thoroughly discussed in [1]. The reflection protocol is a subset of such a MOP.
What is the meaning of "Meta-Object Protocol"? Well, meta information is information about something else seen from a level beyond -- a meta level. So, information about the attribute values of an object, say someBook.author, is information on the object level. But information about the properties of the object itself, about its attributes, its structure, etc. is meta information.



										CONCLUSIONS
										We have presented three design principles for meta-level
										facilities in object oriented programming languages:
										1. Encapsulation. Meta-level facilities must encapsulate
										their implementation.
										2. Stratification. Meta-level facilities must be separated
										from base-level functionality
										3. Ontological Correspondence. The ontology of metalevel
										facilities should correspond to the ontology of the
										language they manipulate.
										Mirror-based systems substantially embody these principles.
										They isolate an object-oriented programming language�’s
										reflective capabilities into separate intermediary objects called
										mirrors that directly correspond to language structures and
										make reflective code independent of a particular
										implementation.
										As a result:
										• Mirrors make remote/distributed development easier.
										• Mirrors make deployment easier because reflection can be
										easily taken out or added, even dynamically.
										The design principles behind mirrors may seem obvious, and
										yet these principles have not been widely applied to the
 *
 *
 *
 ****************************************************************************
 * @version $Id: Reflection.h 2833 2010-08-02 23:12:57Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Core_Reflection_H__
 #define __WOSH_Core_Reflection_H__

 #include <woshDefs.h>
 #include <string>
 #include <string.h>

//  RTTI, but not supported/same on every platform/compiler
//  #include <typeinfo>
//  cout << typeid(obj).name() << endl;
/*
GOALS:
 - identificare nome classe (vera instanza, non super-classi)
 - identificare base classes (in ordine)
 - up/down casting
 - usare RTTI ma anche senza!

IDEA:
 - SE RTTI => dynamic_cast
--------------------------------------------------------------------------------------
CON RTTI 

bool valid = message->getContent()->is(wosh::Variant)
Variant* data = message->getContent()->as(Variant)

message->getContent()->asResponse()		=> message->getContent()->as<Response>()		OK

Response* r = message->getContent()->as("Response"); // HOW?bene che fada server un manager static!?

*/


namespace wosh {


# undef WOSH_QUERY_INTERFACE
# define WOSH_QUERY_INTERFACE(CLASSNAME)												\
		public: virtual bool queryInterface(const char* classname, void** pObj) {		\
					if ( isClass(classname) ) {											\
						*pObj = this;													\
					return true;														\
				 }


/**
 * @brief  Interface macro for IReflection
 * @param CLASSNAME [in] the full class name (such as 'wosh::network::SocketUdp')
 * @return implementation of className() and getClassName()
 * @see    IReflection::className()
 * @see    IReflection::getClassName()
 */
#define WOSH_CLASSNAME(CLASSNAME)														\
		public: static const char* className() { return #CLASSNAME; }					\
		public: virtual inline const char* getClassName() const { return className(); }

/**
 * @brief  Interface macro for IReflection
 * @param BOOLEAN [in] true when the class is abstract; false else
 * @return implementation of isAbstract()
 * @see    IReflection::isAbstract()
 */
#define WOSH_CLASS_ABSTRACT(BOOLEAN)													\
		public: virtual bool isAbstract() const { return BOOLEAN; }

#define WOSH_CLASS_NULL		""

class IReflection  {

/** @name IReflection interface
 * @{
 ******************************************************************************/
	public:
		/**
		 * @brief  Evaluate if the class is abstract.
		 *         Abstract classes cannot be instantiated.
		 * @return true, if the type is an abstract class,
		 *         that is it has pure virtual functions; false else.
		 * @see    WOSH_CLASS_ABSTRACT
		 * @note   RTTI independent
		 */
		virtual bool isAbstract() const = 0;

		/**
		 * @brief  Get the class name (including namespace).
		 * @return constant C string, representing class name, plain text (latin1)
		 * @see    WOSH_CLASSNAME
		 * @note   RTTI independent
		 */
		virtual const char* getClassName() const = 0;

//@}
/** @name IReflection Helpers
 * @{
 ******************************************************************************/
	public:
		/**
		 * @brief  Evaluate if instance is the (exactly) same type of argument.
		 * @param  classname [in] the full class name, including namespace (such as 'wosh::network::SocketUdp')
		 * @return true when the strings are equal
		 * @see    WOSH_CLASSNAME
		 * @note   RTTI independent
		 */
		virtual inline bool isClass( const char* classname ) const {
			if ( classname == NULL ) return false;
			if ( strcmp(getClassName(), classname ) == 0 )
				return true;
			return false;
		 }

		/**
		 * @brief  Get the class name (NOT including namespace).
		 * @return constant C string, representing class name, plain text (latin1)
		 * @see    getClassName()
		 * @note   RTTI independent
		 */
		static const char* getClassNameOnlyOf( const char* full_classname ) {
			if ( full_classname == NULL ) return WOSH_CLASS_NULL;
			return strrchr( full_classname, ':' );
		 }

//@}
/** @name IReflection Helpers - RTTI
 * @{
 ******************************************************************************/
	public:
#ifdef _USE_RTTI

		template <typename T>
		inline bool isKindOf() const {
			return ( dynamic_cast<const T*>(this) != NULL );
		 }

		/**
		 * @brief  . Use: const wosh::Variant* data = GenericClass->as<wosh::Variant>()
		 * @param classname [in] the full class name (such as 'wosh::network::SocketUdp')
		 * @return casted pointer
		 * @note   RTTI dependent
		 */
		template <typename T>
		inline const T* as() const {
			return dynamic_cast<const T*>(this);
		 }

		template <typename T>
		inline T* as() {
			return dynamic_cast<T*>(this);
		 }
#else

		virtual bool queryInterface( const char* classname, void** pObj ) = 0;


#endif //_USE_RTTI
//@}
	public:
		virtual ~IReflection() { }

}; // class def


}; // namespace wosh

#endif //__WOSH_Core_Reflection_H__
